2W - 허블 기반 모니터링

개요

이번 주차는 실리움과 관련된 모니터링 기술과 방법들을 알아본다.
첫번째로 트래픽 관련 추적 도구인 허블을 사용해본다.
허블을 이용하면 트래픽의 흐름을 추적하는데 매우 도움이 되는데, 네트워크 정책 리소스(CiliumNetworkPolicy)를 만들면 더 구체적인 모니터링을 할 수 있게 된다.
그래서 깊게 다루지는 않으나 실습 상에서 관련한 리소스를 만드는 것을 보게 될 것이다.

허블이란


(허블 우주망원경을 아이콘으로 사용하고 있다!)
허블은 실리움과 함께 번들격으로 제공되는 관측가능성 플랫폼으로, 실리움에서 이뤄지는 각종 동작, 메트릭 정보에 대해 가시성을 제공한다.
실리움은 eBPF 기반이기에 커널 영역에서 이뤄지는 동작에 대해 전통적인 스택을 이용해 모니터링하는데 여러 불편함이 있다.
이러한 불편함을 해소해주는 툴로 cilium을 만든 isovalent에서는 허블을 함께 개발하고 있다.
허블은 ebpf 영역의 동작에 대해서 깊고 세부적인 가시성을 제공하면서도 오버헤드를 최소화하는 동적인 접근 방식을 허용한다.

허블은 다음의 질문에 대해 답할 수 있다.

전반적으로 요약하자면, 허블은 트래픽 모니터링에 최적화된 툴이다.
따지자면 Kiali와 비슷한 녀석이라 할 수 있겠다.

허블 구조

허블에는 여러 컴포넌트가 있다.

이때 실리움 에이전트 프로세스 내부에 배치되어 개별 노드에 세팅되는 것을 기본적인 허블이라 부른다.
(그래서 cilium-dbg라는 에이전트 조작 도구로도 확인할 수 있다.)
이 허블이 기본이 되다보니 보통 hubble server, 혹은 hubble embedded라고도 부른다.[1]
허블 서버는 에이전트와 유닉스 도메인 소켓을 기반으로 통신하며 각종 데이터를 가공하고 출력한다.
프로메테우스라고 치면 허블 서버는 익스포터라고 할 수 있겠다.
(참고로 프로메테우스와의 연동을 위해 메트릭 노출이 가능하다)

클러스터 전체 관점에서 모니터링을 할 수 있도록 도와주는 툴은 허블 릴레이(Hubble Relay) 로, 여러 노드에 배치된 허블로부터 데이터를 통합하여 시각화해준다.
사용자 입장에서 그냥 허블이라 한다면 아무래도 이 허블 릴레이를 부르는 것일 테다.

허블에 접근할 때는 같이 배치되는 웹 ui를 쓰거나 아니면 hubble cli를 세팅해서 쓰면 된다.

실습 환경 세팅

사전 지식으로서 많이 설명할 것은 없고, 이제 실습을 해보도록 한다.

이번 실습부터는 처음부터 실리움을 세팅한 환경을 구성한다.
이전의 세팅과 크게 다르지 않으니 몇 가지 수정사항만 체크한다.
kubeadm을 세팅할 때 설정 파일로 kube-proxy가 설치되지 않도록 필드를 넣어주었다.[2]

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
controlPlaneEndpoint: "192.168.10.100:6443"
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/16
kubernetesVersion: 1.33.0
proxy:
  disabled: true

다음으로 실리움 설치 시에는 헬스체킹을 비활성화한다.

helm install cilium cilium/cilium --version $2 --namespace kube-system \
--set k8sServiceHost=192.168.10.100 --set k8sServicePort=6443 \
--set ipam.mode="cluster-pool" --set ipam.operator.clusterPoolIPv4PodCIDRList={"172.20.0.0/16"} --set ipv4NativeRoutingCIDR=172.20.0.0/16 \
--set routingMode=native --set autoDirectNodeRoutes=true --set endpointRoutes.enabled=true \
--set kubeProxyReplacement=true --set bpf.masquerade=true --set installNoConntrackIptablesRules=true \
--set endpointHealthChecking.enabled=false --set healthChecking=false \ # 이 부분 세팅!
--set hubble.enabled=false --set operator.replicas=1 --set debug.enabled=true >/dev/null 2>&1

규모가 큰 클러스터에서는 자원 소모를 줄이기 위해 엔드포인트 헬스체킹을 비활성화하는 것이 좋다.[3]
노드가 10개 이내 정도로 작은 범위일 때만 방화벽이나 하이퍼바이저 세팅으로 인한 임의의 패킷 로스를 추적하기 위해 켜두는 것이 추천된다.

호스트 환경에서 각종 명령어를 쓰고 싶다면 vm 내부에 세팅된 kubeconfig 파일을 꺼내오자.

vagrant scp k8s-ctr:config config
mv ~/.kube/config ~/.kube/config.backup
mv config ~/.kube/config

클러스터 구축이 완료됐다면 이후 디버깅 편의를 위해 별칭과 환경변수를 등록한다.

# cilium 파드 이름
export CILIUMPOD0=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-ctr -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD1=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w1  -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD2=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w2  -o jsonpath='{.items[0].metadata.name}')
echo $CILIUMPOD0 $CILIUMPOD1 $CILIUMPOD2

# 단축키(alias) 지정
alias c0="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- cilium"
alias c1="kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- cilium"
alias c2="kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- cilium"

alias c0bpf="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- bpftool"
alias c1bpf="kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- bpftool"
alias c2bpf="kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- bpftool"

확인

kube-proxy가 없이 노드 조인이 될 때는 다음과 같이 경고 메시지가 발생한다.
image.png
해당 경고가 뜨면 오히려 kube-proxy가 설치되지 않았다는 반증이라 할 수 있겠다.
image.png

실리움은 기본적으로 설치됐고, 모니터링을 위한 허블은 세팅돼있지 않은 상태이다.

cilium status

image.png

클러스터 차원에서 확인할 것들을 몇 가지 본다.

kubectl describe cm -n kube-system kubeadm-config | grep Subnet
k get pods -A -owide 
# 더 명확하게 확인도 가능
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
kubectl get ciliumnode -o json | grep podCIDRs -A2

kubectl get ciliumendpoints -A

실리움을 세팅할 때 파드 cidr 영역은 172 대로 설정했기 때문에 coredns 부터는 해당 ip를 부여받는 것도 확인된다.
저번 주차 마이그레이션하며 설정했던 사항 중 파드 ip 대역은 반영되지 않았지만, 초기부터 세팅할 때는 문제 없이 적용된다.
image.png
각 파드는 실리움에 의해 엔드포인트 관리를 받고 있다.
image.png
같은 역할을 수행하기에 시큐리티 신원을 가지는 것을 확인할 수 있다.

실리움 에이전트의 상태도 간단하게 살펴본다.

c0 monitor
c0 config
c0 status
c0 metrics list

image.png
현재는 실리움 에이전트 작업과 설정에 대해 노출되는 메트릭이 있어 이것을 직접 확인하는 방법이 존재한다.
image.png
그러나 이후 허블을 설치하면 네트워크 패킷 단에서 일어나는 메트릭까지 더 자세하게 추적이 가능해진다.

다음은 노드에 직접 들어가서 확인할 것들을 몇 개 정리했다.

ip a s
ifconfig | grep -iEA1 'eth[0-9]:'


iptables -t nat -S

ss -tnlp | grep -iE 'cilium|hubble'

실리움 헬스체킹 인터페이스 역시 생성되지 않은 것이 확인된다.
image.png
또한 kube-proxy가 없으므로 서비스에 대해 만들어지는 iptables 역시 확인되지 않는다.
image.png
각 노드에 오픈된 tcp 소켓 정보를 본다.
image.png

허블 설치

간단하게는 이 정도만 하더라도 허블을 이용할 수 있다.[4]

helm upgrade cilium cilium/cilium --version 1.17.6 \
   --namespace kube-system \
   --reuse-values \
   --set hubble.relay.enabled=true \
   --set hubble.ui.enabled=true

이후 실습과 편의 세팅을 위해 몇 가지 설정을 추가하여 넣어준다.

helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set hubble.ui.service.type=NodePort \ # ui
--set hubble.ui.service.nodePort=31234 \ # ui
--set hubble.export.static.enabled=true \
--set hubble.export.static.filePath=/var/run/cilium/hubble/events.log \
--set prometheus.enabled=true \ # prom
--set operator.prometheus.enabled=true \ # prom
--set hubble.metrics.enableOpenMetrics=true \ # prom
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}" \ # prom
--set hubble.tls.auto.enabled=true \
--set hubble.tls.auto.method=helm  \
--set hubble.tls.auto.certValidityDuration=1095 

web ui를 접근하기 위해 포트포워딩을 하는 것도 가능하나, 먼저 노드포트로 접근 가능하게 경로를 뚫어 접근하는 것도 방법이다.
여기에 프로메테우스 형태로 메트릭을 전달할 수 있도록 추가적인 세팅을 넣어주었다.

추가적으로 허블에 tls 통신을 하도록 수정을 해주었다.[5]
허블과 허블 릴레이는 기본적으로 단순한 tcp 통신을 통해 데이터를 주고 받는다.
그렇기에 중간자 공격이나 패킷 탈취에 취약한 편이므로 가급적 tls 세팅을 해주는 것이 좋다.
위 설정을 넣어주면 mtls가 되도록 설정된다.
현재 세팅은 단순히 헬름 조작이 가해질 때만 인증서가 갱신되도록 설정돼있다.
그러나 엄밀하게 인증서 관리를 하기 위해서는 Cert Manager를 함께 이용하는 것이 추천된다.

확인

허블이 제대로 세팅된 것을 확인할 수 있다.
image.png

소켓 정보를 볼 때 새로운 몇 가지가 추가된 것을 확인할 수 있다.
image.png

k -n kube-system get daemonsets.apps cilium -oyaml | grep 4244 -B4

4244는 실리움 에이전트가 노출하는 메트릭 포트로, 궁극적으로는 허블이 메트릭을 노출하는 경로라고 보면 되겠다.

허블과 관련하여 여러 서비스가 생성된 것을 확인할 수 있다.
image.png
실리움 에이전트를 향하는 서비스의 경우 엔드포인트로 노드 주소를 가지고 있다.
image.png
반면 허블 릴레이, 이를 시각화해주는 허블 ui의 경우에는 파드 ip 대역으로 엔드포인트가 잡히는 것을 볼 수 있다.

현재 kubeconfig가 요청이 정상적으로 vm에 들어가듯 vm ip 대역에 대한 라우팅 경로는 이미 vm으로 흘러가도록 되어 있어 노드포트를 이용해 쉽게 웹 ui를 확인할 수 있다.
네임스페이스를 기준으로 모니터링을 진행할 수 있다.
image.png
Kiali와 같이 허블 ui는 최근에 발생한 트래픽을 보여주는 것에 초점을 두고 있다.
그러므로 간단하게라도 트래픽을 발생시켜야 제대로 시각화를 할 수 있다.

몇 가지 정보를 더 확인해보자.

kubectl describe cm -n kube-system hubble-relay-config 

image.png
허블 릴레이는 먼저 hubble-peer 서비스를 기반으로 허블에 접근해 데이터를 모은다.
각 허블은 4244포트로 트래픽을 노출하고 있으며, 릴레이 자체는 4245에서 노출한다.

k -n kube-system logs hubble-relay-5dcd46f5c-jgzcp

image.png
허블 릴레이는 연결 시 gRPC를 활용한다.
이때 초기에 세팅한 대로 mtls 통신을 하는 것 역시 확인할 수 있다.

k -n kube-system get pod hubble-ui-76d4965bb6-mb2sd -oyaml

hubble-ui는 nginx를 기반으로 동작하며, 해당 파일 정보는 컨피그맵에서 확인할 수 있다.
image.png
조금 더 파보자면 nginx는 프론트엔드로서 백엔드 컨테이너로 프록시 패스를 할 뿐이다.
image.png

hubble cli 이용

허블 릴레이에 조금 더 직접적으로 접근할 수 있도록 hubble cli를 설치해본다.

HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
HUBBLE_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
sudo tar xzvfC hubble-linux-${HUBBLE_ARCH}.tar.gz /usr/local/bin

echo $0 | grep zsh -q
if [ $? -eq 0 ]; then
  echo "auto completion setting for zsh"
  mkdir -p ~/.oh-my-zsh/custom/plugins/hubble
  hubble completion zsh >> ~/.oh-my-zsh/custom/plugins/hubble/hubble.plugin.zsh
  # This should be tested on your zshrc for sure
  sed -i '/^plugins=/a \  hubble' ~/.zshrc
  source ~/.zshrc
else
  echo "auto completion setting for bash"
  echo "If you want auto complete for other shell, do it your own"
  hubble completion bash >> ~/.bashrc
  source ~/.bashrc
fi

hubble cli는 직접적으로 릴레이에 접촉한다.
현재 릴레이에 대해 노드포트 세팅을 하지 않았으므로 간단하게 포트포워딩시킨다.[]

cilium hubble port-forward& # 118516
hubble status
hubble observe
hubble observe -h
hubble observe -f

image.png
신원이 확인되는 트래픽에 대해서는 ip 주소가 아니라 바로 해당 리소스 이름을 적어서 표기한다.
ID가 해당 트래픽을 보내거나 받는 주체이기 때문에 이를 기반으로 보여주게 되는 것이다.

http 요청을 날려본다.

kaf check.yaml
keti curl-pod -- curl webpod 
hubble observe -n default

image.png
dns 트래픽, http 요청이 있었음을 포트 번호를 기반으로 어렴풋이 확인할 수 있다.
그러나 구체적으로 L7레벨에서 어떤 트래픽일지는 명확하게 탐지하기 어려운데, 이 부분은 이후에 추가적으로 확인하게 될 것이다.

cli로도 결국 동일한 정보를 볼 수 있다.
image.png
visual 버튼에서 숨김처리된 트래픽까지 가시화시키면 이렇게 조금 더 풍부한 정보를 확인할 수 있게 된다.
image.png
그러나 여기에서도 L7 레벨의 무언가를 볼 수 없다는 것은 미리 확인해두자.
image.png
그래서 아쉽게 tls 통신 여부를 당장 확인하는 것은 조금 어렵다.
대신 다음의 명령을 통해 허블이 tls 통신을 하도록 설정돼있다는 것은 당장 확인할 수 있다.

kubectl get configmap -n kube-system cilium-config -oyaml | grep hubble-disable-tls

image.png

실리움을 모니터링하고 확인할 수 있는 수단이 너무 많아 아직 헷갈리는데, 다양한 명령어를 계속 사용하면서 익숙해질 필요가 있어보인다.
image.png
아이덴티티는 각 노드의 실리움 에이전트에서 직접적으로 알아낼 수도 있다.
image.png
통합적으로 확인하는 것을 우선시하되, 차선으로 다른 방법이 있다는 것만 염두하자.

c1 service list
c0 bpf lb list
c1 map list --verbose

스타워즈 데모 실습

공식 문서에서 가이드라인으로 제공하는 데모를 사용해본다.[6]
이 예제의 구체적인 목적은 실리움에서 제공하는 네트워크 정책을 적용하는 것이다.
근데 이를 위해 조금씩 모니터링할 구석이 있기도 하고, L7 모니터링을 위해서는 네트워크 정책이 필수적이라 자연스럽게 이 예제를 먼저 활용해본다.

각 블록은 파드를 나타내며, 왼쪽의 두 파드는 스타워즈 컨셉 상 우주선, 오른쪽 파드 deathstar는 선박이 착륙할 수 있는 정거장 정도의 역할이다.
(스타워즈를 정확하게는 몰라 개념은 조금 틀릴 수 있다.)
이 기본적인 상태에서 하려는 실습은 다음과 같다.

기본 통신

먼저 기본 예제들을 적용해보자.

kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/http-sw-app.yaml
kubectl get deploy,svc,ep deathstar

c0 endpoint list 
c1 endpoint list 
c2 endpoint list

image.png
xwing과 tiefighter는 deathstart의 서비스로 요청을 날릴 수 있다.
간단하게 모니터링하며 요청을 날려본다.

XWINGID=$(kubectl get ciliumendpoints.cilium.io | grep xwing | awk  '{ print $2 }')
TIEFIGHTERID=$(kubectl get ciliumendpoints.cilium.io | grep tiefighter | awk  '{ print $2 }')
DEATHSTARID=$(kubectl get ciliumendpoints.cilium.io | grep deathstar | awk  '{ print $2 }' | head -n 1)
echo $XWINGID $TIEFIGHTERID $DEATHSTARID

## 각 노드의 에이전트에서 모니터
c0 monitor -v -v
c1 monitor -v -v
c2 monitor -v -v

hubble observe -f --from-identity $XWINGID
hubble observe -f --protocol tcp --from-identity $DEATHSTARID
hubble observe -f  --to-identity $DEATHSTARID
# hubble observe -f --protocol udp --from-identity $XWINGID
# hubble observe -f --protocol tcp --from-identity $XWINGID

kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
while true; do kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done

# 호출 시도 2
while true; do kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done

트래픽을 추적할 때는 신원을 기반으로 필터링을 하는 것이 가능하다.
이를 기반으로 보고 싶은 데이터에 한정하여 패킷을 따본다.

에이전트에서는 다음과 같이 패킷 덤프를 따듯이 트래픽을 추적할 수 있다.
image.png
어떤 엔드포인트에서 발생한 트래픽인지, 그래서 신원 상으로는 어디에서 어디로 보내는 건지, 어떤 트래픽인지 등의 정보가 출력된다.

허블을 통해 트래픽을 추적하면 조금 더 직관적으로 흐름을 볼 수 있다.
image.png
위 트래픽은 xwing에서 날아가는 트래픽을 기준으로 캡쳐했는데, 반대로 --to-identity 옵션을 통해 deathstar로 날아오는 트래픽을 기준으로 추적하는 것도 가능하다.
비슷한 흐름을 허블 ui를 통해서도 확인할 수 있다.
image.png
그런데 허블에서는 tcp 상의 여러 트래픽에 대해 각각을 명확히 표시해주지 않아서 그다지 시각화가 좋아보이지는 않는다는 인상을 조금 받았다.

L4 레벨 정책 적용

먼저 L4 레벨에서 제한을 거는 네트워크 정책 리소스를 만든다.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "L3-L4 policy to restrict deathstar access to empire ships only"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
  - fromEndpoints:
    - matchLabels:
        org: empire
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP

CiliumNetworkPolicy는 보다시피 쿠버네티스의 네트워크 폴리시보다 더 많은 기능을 가지고 있다.
간단하게 보자면 deathstar과 관련되는 트래픽 중 들어오는 트래픽은 empire 소속이어야만 한다고 제한을 걸었다.
흔히 그렇듯 네트워크 폴리시를 만드는 순간 명시되지 않은 다른 트래픽은 거부된다는 것에 유의하자.

while true; do kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done
while true; do kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done

hubble observe -f --protocol tcp --from-identity $XWINGID
hubble observe -f --protocol tcp --from-identity $TIEFIGHTERID

해당 정책을 적용하자 xwing에서 나가는 트래픽은 더 이상 성공하지 않는다.
image.png
허블로 추적해보면 해당 상황이 더 명확하게 확인된다.
image.png
보다시피 tiefighter에서의 트래픽은 정책을 통과했고 그대로 진행된다.
그러나 xwing에서의 트래픽은 인그레스 거부로 인해 DROP되는 것을 확인할 수 있다.
image.png
웹 상으로도 해당 상황을 확인할 수 있다.
image.png
막상 웹으로 확인해보면 xwing에서의 트래픽 수가 현저히 적은 것을 볼 수 있다.
이것은 패킷이 드랍되어 curl 명령이 응답을 무작정 기다리면서 발생하는 지연이다.

정책이 적용된 상황은 다음의 명령어들을 통해 확인할 수 있다.

k describe cnp
c1 policy get
c1 endpoint list

L4의 정책은 실리움 에이전트 레벨에서 적용되기 때문에 해당 정보를 에이전트로부터 확인할 수 있다.
image.png

L7 레벨 정책 적용 - 엔보이 활용

실리움 네트워크 정책 리소스의 특징은 L7 영역의 정책도 넣을 수 있다는 것이다.
이때 L7 정책 처리는 엔보이가 담당하게 되는데, 마치 이스티오의 앰비언트 모드를 연상케 하는 방식이라 할 수 있겠다. 누가 먼저일까

구체적으로 트래픽이 이동하게 되는 시점은 네트워크 인터페이스를 지나 TC 훅에 걸렸을 때이다.

참고로 실리움을 세팅할 때 envoy.enabled=true가 되어있어야 엔보이가 세팅된다.
L7의 정책을 엔보이에 위임하여 분리하는 것은 다음의 장점을 가지고 있다.

엔보이로 트래픽을 보내는 역할은 해당 노드의 에이전트가 전담한다.[7]
둘 사이의 통신은 유닉스 도메인 소켓을 통해 이뤄진다.

이전의 정책 리소스를 업데이트해서 적용해본다.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "L7 policy to restrict access to specific HTTP call"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
  - fromEndpoints:
    - matchLabels:
        org: empire
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "POST"
          path: "/v1/request-landing"

다시 확인해본다.

while true; do kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done
while true; do kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing ; sleep 5 ; done

hubble observe -f --protocol tcp --from-identity $XWINGID
hubble observe -f --protocol tcp --from-identity $TIEFIGHTERID

결과만 놓고 보자면 위에서 발생한 상황과 비슷하다.
image.png
그러나 이제 트래픽 추적 시 L7 프로토콜인 http를 반영한 데이터가 출력되는 것을 확인할 수 있다.
아울러 다른 경로로는 접근이 거부된다.

kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port 

image.png
보다시피 원래 잘만 트래픽을 보내던 tiefighter도 다른 경로로 보낼 경우 트래픽이 DROP되어버린다.
xwing은 말할 것도 없다..
image.png
웹으로 확인하면 이제 http 경로 상의 트래픽을 명시하여 시각화하는 것을 확인할 수 있다.
image.png
L7정책이 적용된다는 것보다도 이렇게 L7 모니터링이 가능하다는 것이 더 신기한 듯..

여기에서 엔보이는 리버스 프록시로서 기능하기 때문에 deathstar 파드가 위치한 노드에서 엔보이 로그를 뜯어보면 단서가 나온다.

k -n kube-system logs cilium-envoy-w8wpj

image.png
엔보이에 정책이 적용됐다는 것을 확인할 수 있다.

왜 엔보이는 클라이언트 사이드에 있지 않을까

이스티오 기준으로 봤을 때는 사이드카 프록시로서 엔보이는 나가는 트래픽에 대해서도 제어를 하며 대체로 정책 적용이 요청을 보내는 측의 엔보이에서 먼저 적용한다.
서비스 메시를 도입해본 입장에서는 이러한 방식도 충분히 가능하다 생각할지도 모르겠다(나만 그랬나)
어차피 CNI로서 나가는 트래픽도 실리움이 전부 관리하니 이그레스 트래픽에 대해 엔보이를 거치게 하는 것이 불가능한 선택지는 아닐 것이다.
그러나 클라이언트 사이드 방식은 정책 일괄 적용이나 자원 소모에 있어서 그다지 효율적인 선택지가 아니기도 하다.
더구나 외부에서 들어오는 트래픽에 대해서는 정책을 적용하기 어려운 상황이 나오기도 한다.
이스티오 역시 이러한 문제점을 해결하고자 앰비언트 모드에서 웨이포인트는 리버스 프록시로서 동작을 정의했다.

엔보이에 적용된 설정 정보는 아래와 같이 확인할 수 있다.

c1  envoy admin 

config 관련 정보를 찾다보면 이렇게 적용된 설정도 나온다.
image.png
사실 엔보이로 트래픽을 라우팅하는 설정을 출력하고 싶었지만 이 부분은 실패했다..

L7 관련 기능 중에는 민감한 데이터를 모니터링 시에 마스킹하는 기능도 있다.
이를 redact라고 하는데, 실습하진 않지만 아래의 명령어를 통해 적용할 수 있다.

helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
  --set extraArgs="{--hubble-redact-enabled,--hubble-redact-http-urlquery}"

이 명령어는 url 쿼리 부분을 마스킹하여 모니터링 간에는 출력되지 않도록 한다.

아래는 순수 모니터링 용으로 정책을 설정하는 예시로, 나가는 트래픽을 그냥 허용한다.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "l7-visibility"
spec:
  endpointSelector:
    matchLabels:
      "k8s:io.kubernetes.pod.namespace": default
  egress:
  - toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": default
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      - port: "8080"
        protocol: TCP
      rules:
        http: [{}]

모니터링을 하기 위해 리소스를 만들고 실질적으로는 아무런 제한을 가하지 않는다.
다만 으레 네트워크 정책들이 그렇듯이 이 정책을 적용하는 순간 기본으로 전부 열려있던 통로는 막히기 때문에, 명시되지 않은 다른 포트로의 접근은 차단될 것이다.
아무튼 당장 파드에서 사용할 트래픽에 대해서는 전부 개방이 되어 있어 상관은 없다.

결론

L7 정도의 모니터링을 위해서는 L7 정책을 넣어야 한다는 것이 조금 특이한 사용 방식이라고 느껴진다.
어쩔 수 없겠다는 생각이 드는 한편 사용감이 그다지 좋게 느껴지지 않기도 한다.
아무튼 L7 레벨의 데이터를 확인하고 모니터링하기 위해서는 반드시 L7과 관련되는 정책 리소스를 만들어야만 한다는 것에 유의하자.

이전 글, 다음 글

다른 글 보기

이름 index noteType created
1W - 실리움 기본 소개 1 published 2025-07-19
1W - 클러스터 세팅 및 cni 마이그레이션 2 published 2025-07-19
1W - 기본 실리움 탐색 및 통신 확인 3 published 2025-07-19
2W - 허블 기반 모니터링 4 published 2025-07-26
2W - 프로메테우스와 그라파나를 활용한 모니터링 5 published 2025-07-26
3W - 실리움 기본 - IPAM 6 published 2025-08-02
3W - 실리움 기본 - Routing, Masq, IP Frag 7 published 2025-08-02
4W - 실리움 라우팅 모드 실습 - native, vxlan, geneve 8 published 2025-08-09
4W - 실리움 로드밸런서 기능 - 서비스 IP, L2 9 published 2025-08-09

하위 문서

이름 is-folder index noteType created
1W - 실리움 기본 소개 false 1 published 2025-07-19
1W - 클러스터 세팅 및 cni 마이그레이션 false 2 published 2025-07-19
1W - 기본 실리움 탐색 및 통신 확인 false 3 published 2025-07-19
2W - 허블 기반 모니터링 false 4 published 2025-07-26
2W - 프로메테우스와 그라파나를 활용한 모니터링 false 5 published 2025-07-26
3W - 실리움 기본 - IPAM false 6 published 2025-08-02
3W - 실리움 기본 - Routing, Masq, IP Frag false 7 published 2025-08-02
4W - 실리움 라우팅 모드 실습 - native, vxlan, geneve false 8 published 2025-08-09
4W - 실리움 로드밸런서 기능 - 서비스 IP, L2 false 9 published 2025-08-09

관련 문서

지식 문서, EXPLAIN

이름23is-folder생성 일자
E-이스티오 컨트롤 플레인 성능 최적화false2025-05-18 02:29
E-이스티오 컨트롤 플레인 메트릭false2025-05-18 15:45
Thanosfalse2025-02-26 20:24
Prometheusfalse2025-02-26 16:16
Loki- 2024-04-08
Grafana- 2024-04-08
황금 신호false2025-05-16 14:32
관측 가능성false2025-02-24 14:26
설치 요구사항false2025-07-06 10:34
ebpf 동작 가이드false2025-07-06 10:49
Hubblefalse2025-07-06 10:38
0주차 검증false2025-07-06 12:46
OpenTelemtry Operatorfalse2025-04-29 21:18
Prometheus-Adapterfalse2025-03-04 17:01
Prometheus Operatorfalse2025-03-30 15:13
Kube-State-Metricsfalse2025-02-28 13:54
kubestrfalse2025-02-19 14:36
OpenTelemetryfalse2025-02-28 23:37
Jaegerfalse2025-04-29 00:33
Kialifalse2025-04-28 23:41
Istio Telemetryfalse2025-04-08 15:18
Istio Observabilitytrue2025-04-28 00:17
Ciliumfalse2025-06-15 23:42

기타 문서

Z0-연관 knowledge, Z1-트러블슈팅 Z2-디자인,설계, Z3-임시, Z5-프로젝트,아카이브, Z8,9-미분류,미완
이름11코드타입생성 일자
4주차 - 관측 가능성Z5project2025-02-23 19:54
4주차 - opentelemetry 데모Z5project2025-03-01 14:14
4W - 프로메테우스 스택을 통한 EKS 모니터링Z8published2025-02-28 23:45
실리움 2주차Z8topic2025-07-20 19:05
4W - EKS 모니터링과 관측 가능성Z8published2025-02-28 23:44
1W - 간단한 장애 상황 구현 후 대응 실습Z8published2025-04-10 20:06
4W - 이스티오 메트릭 확인Z8published2025-05-03 22:15
6W - 이스티오 컨트롤 플레인 성능 최적화Z8published2025-05-18 02:29
4W - 오픈텔레메트리 기반 트레이싱 예거 시각화, 키알리 시각화Z8published2025-05-03 22:49
4W - 이스티오 메트릭 커스텀, 프로메테우스와 그라파나Z8published2025-05-03 22:16
관찰 가능성 패턴Z9-2024-00-13

참고


  1. https://docs.cilium.io/en/latest/internals/hubble/ ↩︎

  2. https://kubernetes.io/docs/reference/config-api/kubeadm-config.v1beta4/ ↩︎

  3. https://docs.cilium.io/en/stable/operations/performance/scalability/report/ ↩︎

  4. https://docs.cilium.io/en/stable/observability/hubble/setup/ ↩︎

  5. https://docs.cilium.io/en/stable/observability/hubble/configuration/tls/ ↩︎

  6. https://docs.cilium.io/en/stable/gettingstarted/demo/ ↩︎

  7. https://docs.cilium.io/en/latest/security/network/proxy/envoy/ ↩︎